import Blockutils from "@/utils/BlockUtils";
import Mota, { MotaInterface } from "@/mota";
import ScrollTool from '@/mota/tools/ScrollTool';
import { GetItemEmit } from "@/mota/data/ItemDataUnit";
import { ImageName } from "@/mota/data/ImageLoader";

type StoreItem = [string, "gold" | GetItemEmit[], GetItemEmit[]];

export default class StoreUtils extends ScrollTool<StoreItem> implements MotaInterface {
    public readonly Mota: Mota;

    public block: Blockutils = new Blockutils();

    public ZIndex: number = 4;

    public InitialGold: number = 20;

    public PayGold: number = 0;

    public image: ImageName = "贪婪之神";

    public title: string = "";

    public descritp: () => string = () => "";

    public get NeedGold() {
        return this.InitialGold + this.PayGold;
    }

    public constructor(mota: Mota) {
        super({
            Left: 7.3,
            Top: 4,
            Width: 4.7,
            Height: 5,
            Padding: 0.1,
            ItemWidth: 4.7 - 0.3,
            ItemHeight: 1.2,
            ItemPadding: 0.1,
            ScrollWidth: 0.1,
        });
        this.SelectIndex = 0;
        this.Mota = mota;
    }

    public get isOpen() {
        return this.block.IsBlockUp;
    }

    public Open(name: ImageName): Promise<void> {
        this.image = name;
        if (name === "老人") {
            this.title = "经验老人";
            this.descritp = () => "勇士，如果你拥有足够的经验，我将能为你提供一些能力";
            this.List.Value = [
                ["综合能力(100经验)", [["exp", 100]], [["hp", 1000], ["attack", 7], ["defence", 7]]],
                ["攻击 +5(30经验)", [["exp", 30]], [["attack", 5]]],
                ["防御 +5(30经验)", [["exp", 30]], [["defence", 5]]]
            ];
        } else {
            this.title = name;
            this.descritp = () => `勇士，如果你拥有${this.NeedGold}金币，我将能为你提供一些能力`;
            this.List.Value = [
                ["生命 +800", "gold", [["hp", 800]]],
                ["攻击 +3", "gold", [["attack", 3]]],
                ["防御 +3", "gold", [["defence", 3]]]
            ];
        }
        return this.block.Wait();
    }

    public InView(): boolean {
        const { isOpen } = this;
        return isOpen;
    }
    public JudgeKey: MotaInterface["JudgeKey"] = (keyUtils): void => {
        if (!this.InView()) { return; }

        const { Mota, SelectItem, image } = this;
        const { tip, hero: { Attribute } } = Mota;

        for (const key of keyUtils.keyHistory) {
            if (key === "Escape") {
                this.block.Release();
                keyUtils.delete(key);
            }
            else if (key === "Enter" || key === " ") {
                if (SelectItem !== undefined) {
                    let reduceRes: string | undefined;
                    if (SelectItem[1] === "gold") {
                        reduceRes = Attribute.ReduceAttribute([["gold", this.NeedGold]]);
                        if (reduceRes === undefined) {
                            this.PayGold++;
                        }
                    } else {
                        reduceRes = Attribute.ReduceAttribute(SelectItem[1]);
                    }
                    if (reduceRes !== undefined) {
                        tip.AddIconMessage(image, `缺少${reduceRes}`);
                    } else {
                        const addRes = Attribute.AddAttribute(SelectItem[2]);
                        tip.AddIconMessage(image, `获得${addRes}`);
                    }
                }
                keyUtils.delete(key);
            } else if (key === "ArrowUp") {
                this.SelectLastRow(true);
                keyUtils.delete(key);
            }
            else if (key === "ArrowDown") {
                this.SelectNextRow(true);
                keyUtils.delete(key);
            }
        }
    }

    public Draw: MotaInterface["Draw"] = (draw) => {
        if (!this.InView()) { return; }

        const { image, title } = this;

        const { _2d } = draw;

        _2d.save();

        draw.DrawBackground(["石地板", [6, 1, 12, 9]]);

        _2d.textBaseline = "top";
        _2d.textAlign = "center";
        _2d.fillStyle = "#FFFFFF";
        draw.SetFont(600, 1 / 2, "Mota");
        draw.fillText(title, 10.2, 1.2);

        draw.DrawUnti([image, true, [6.5, 1.7], "run"]);
        draw.SetLineWidth(1 / 16);
        _2d.strokeStyle = "#FFFFFF";
        draw.strokeRect(6.5, 1.7, 1, 1);

        _2d.textBaseline = "top";
        _2d.textAlign = "left";
        _2d.fillStyle = "#FFFFFF";
        draw.SetFont(400, 1 / 2, "Mota");
        draw.DrawTextAutoLine(this.descritp(), 7.8, 1.9, 1 / 2, 1.1, 4.75);

        _2d.textBaseline = "middle";
        _2d.textAlign = "center";
        _2d.fillStyle = "#FFFFFF";
        draw.SetFont(600, 1 / 2, "Mota");

        let selectSize: readonly [number, number, number, number] | undefined = undefined;
        for (const [[desc], isSelect, [x, y, w, h], [bx, by, bw, bh]] of this.GetItemsSize()) {
            draw.fillText(desc, x + w / 2, y + h / 2);
            if (isSelect) {
                selectSize = [bx, by, bw, bh];
            }
        }
        if (selectSize) {
            draw.SetLineWidth(1 / 16);
            _2d.strokeStyle = "#00FF00";
            draw.strokeRect(...selectSize);
        }
        {
            const scrollSize = this.GetScrollSize();
            if (scrollSize) {
                const [[x, y, w, h], [sx, sy, sw, sh]] = scrollSize;
                _2d.fillStyle = "#00000044";
                draw.fillRect(x - 0.05, y - 0.05, w, h);
                _2d.fillStyle = "#000";
                draw.fillRect(sx - 0.05, sy - 0.05, sw, sh);
            }
        }

        draw.SetLineWidth(1 / 16);
        _2d.strokeStyle = "#FFFFFF";
        draw.strokeRect(6, 1, 7, 9);

        _2d.restore();
    }
}